package com.kosmos.dubhe.wxcp.channel;

import com.kosmos.dubhe.wxcp.config.ChannelProperties;
import com.kosmos.dubhe.wxcp.utils.Sm2Encryption;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.utils.URIBuilder;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;

import java.io.IOException;
import java.net.URISyntaxException;
import java.util.concurrent.BlockingDeque;
import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingDeque;
import java.util.concurrent.TimeUnit;

import static org.apache.http.HttpHeaders.USER_AGENT;


/**
 * @author wukai
 */
@Slf4j
@RequiredArgsConstructor
public class WechatBlockingQueueChannel
        implements WechatChannel {


    private final ChannelProperties setting;

    private BlockingDeque<WechatMessage> queue;

    private boolean listening = true;

    @Override
    public void init() {
        queue = new LinkedBlockingDeque<>(1000);
        Executors.newSingleThreadExecutor().execute(this::listen);
    }

    public void stop() {
        listening = false;
    }

    public void listen() {
        while (listening) {
            try {
                WechatMessage message = this.queue.poll(10000, TimeUnit.MILLISECONDS);
                if (null != message) {
                    fireWechat(message);
                    Thread.sleep(2000);
                }
            } catch (InterruptedException e) {
                break;
            } catch (IOException | URISyntaxException | IllegalArgumentException e) {
                log.error("WechatBlockingQueueChannel poll error", e);
            } catch (Exception e) {
                log.error("WechatBlockingQueueChannel poll error", e);
            }
        }

    }

    public void fireWechat(WechatMessage message) throws Exception {
        if (!setting.isEnable()) {
            return;
        }
        log.debug("WechatBlockingQueueChannel fireWechat message:{} ", message);
        URIBuilder builder = new URIBuilder(setting.getWxcpUrl());
        String tag = message.getTag();
        if (null != tag && tag.length() > 0) {
            builder.addParameter("tagId", message.getTag());
            builder.addParameter("toTag", message.getTag()); // bywukai MSUCITY
        }
        String userCode = message.getUserCode();
        if (null != userCode && userCode.length() > 0) {
            builder.addParameter("userCode", message.getUserCode());
        }

        String userName = message.getUserName();
        if (null != userName && userName.length() > 0) {
            builder.addParameter("userName", message.getUserName());
        }

        if (!(null != tag && tag.length() > 0) && !(null != userCode && userCode.length() > 0) && !(null != userName && userName.length() > 0)) {
            String msg = "message tag[" + tag + "] or userCode[" + userCode + "] or userName[" + userName + "] not " +
                    "null both ";
            throw new IllegalArgumentException(msg);
        }

        String content = "";
        if (null != message.getTitle() && message.getTitle().length() > 0) {
            content = message.getTitle() + "\r\n";
        }
        if (null != message.getContent() && message.getContent().length() > 0) {
            content += message.getContent();
        } else {
            throw new IllegalArgumentException("message content not null ");
        }
        builder.addParameter("content", Sm2Encryption.encryptToBase64(content, setting.getPublicKey()));

        CloseableHttpClient client = HttpClients.createDefault();
        HttpGet request = new HttpGet(builder.build());
        request.addHeader("User-Agent", USER_AGENT);

        CloseableHttpResponse response = client.execute(request);

        if (200 != response.getStatusLine().getStatusCode()) {
            log.error("WechatBlockingQueueChannel send message faill... message: {} ", message);
        }
    }

    protected void sendMessage(WechatMessage message) {
        if (null != message) {
            this.queue.push(message);
        } else {
            log.warn("WechatBlockingQueueChannel wanna send message null message ... ");
        }
    }

    protected void sendMessage(String title, String content, String userCode, String toTag, String userName) {
        this.sendMessage(new WechatMessage(title, content, userCode, toTag, userName));
    }

    @Override
    public void broadcast(String content) {
        broadcast(setting.getDefaultMessageTitle(), content, setting.getDefaultMessageTag());
    }

    @Override
    public void broadcast(String title, String content, String toTag) {
        sendMessage(title, content, null, toTag, null);
    }


    @Override
    public void notify(String content) {
        notify(setting.getDefaultMessageTitle(), content, setting.getDefaultMessageUserCode());
    }

    @Override
    public void notify(String title, String content, String userCode) {
        sendMessage(title, content, userCode, null, null);
    }

    @Override
    public void alert(String content, String userName) {
        alert(setting.getDefaultMessageTitle(), content, userName);
    }

    @Override
    public void alert(String title, String content, String userName) {
        sendMessage(title, content, null, null, userName);
    }


    @Override
    public void destroy() {
        stop();
    }
}
